﻿using OpenTK;

namespace Painter3D.RenderSys.RenderObject
{
    /// <summary>
    /// 使用时必须保证GL环境准备完毕
    /// </summary>
    static class InnerShape
    {
        /// <summary>
        /// 获得一个正方形片面的顶点数据
        /// </summary>
        /// <returns>顶点数据</returns>
        public static VertexData Quad()
        {
            return new ElementVertexData(
            new float[]{
                1.0f,   1.0f,   0.0f,
                1.0f,   -1.0f,  0.0f,
                -1.0f,  -1.0f,  0.0f,
                -1.0f,  1.0f,   0.0f,
            }, new float[]{
                1.0f,   1.0f,
                1.0f,   0.0f,
                0.0f,   0.0f,
                0.0f,   1.0f,
            }, new uint[]{
                0,3,1,
                1,3,2,
            }, OpenTK.Graphics.OpenGL4.BeginMode.Triangles);
        }
        /// <summary>
        /// 获得一个正方体盒子的顶点数据
        /// </summary>
        /// <returns>顶点数据</returns>
        public static VertexData Box()
        {
            return new ElementVertexData(
            new float[]{
                1.0f,   1.0f,   1.0f,
                1.0f,   -1.0f,  1.0f,
                -1.0f,  -1.0f,  1.0f,
                -1.0f,  1.0f,   1.0f,
                1.0f,   1.0f,   -1.0f,
                1.0f,   -1.0f,  -1.0f,
                -1.0f,  -1.0f,  -1.0f,
                -1.0f,  1.0f,   -1.0f,
            }, new float[]{
                1.0f,   1.0f,
                1.0f,   0.0f,
                0.0f,   0.0f,
                0.0f,   1.0f,
                1.0f,   1.0f,
                1.0f,   0.0f,
                0.0f,   0.0f,
                0.0f,   1.0f,
            }, new uint[]{
                0,3,1,
                1,3,2,
                4,5,7,
                6,7,5,
                1,5,4,
                1,4,0,
                2,7,6,
                2,3,7,
                0,4,7,
                0,7,3,
                5,1,6,
                6,1,2
            }, OpenTK.Graphics.OpenGL4.BeginMode.Triangles);
        }
        /// <summary>
        /// 获得一个坐标系游标的顶点数据
        /// </summary>
        /// <returns>顶点数据</returns>
        public static VertexData XYZCoord()
        {
            return new ElementVertexData(
            new ShaderInfo.VertexRequestTagEnum[]{
            ShaderInfo.VertexRequestTagEnum.Position,
            ShaderInfo.VertexRequestTagEnum.Color,
        }, new float[][]{
            //position
            new float[]{
                0.0f,   0.0f,   0.0f,
                1.0f,   0.0f,   0.0f,
                0.0f,   1.0f,   0.0f,
                0.0f,   0.0f,   1.0f,
            },
            //color
            new float[]{
                1.0f,   1.0f,   1.0f,
                1.0f,   0.0f,   0.0f,
                0.0f,   1.0f,   0.0f,
                0.0f,   0.0f,   1.0f,
            },
        }, new uint[]{
            0,1,
            0,2,
            0,3,
        }, OpenTK.Graphics.OpenGL4.BeginMode.Lines);
        }
        /// <summary>
        /// 获得一个网格平面的顶点数据
        /// </summary>
        /// <param name="range">坐标范围</param>
        /// <param name="divid">坐标细分</param>
        /// <returns>顶点数据</returns>
        public static VertexData Grid(float range, float divid, int normalAxe = 2)
        {
            int sideCount = (int)(range / divid);
            int count = (int)(range / divid * 2 + 1);
            float[] position = new float[count * 4 * 3];
            int axe1 = (1 + normalAxe) % 3;
            int axe2 = (2 + normalAxe) % 3;
            int axe3 = (3 + normalAxe) % 3;


            for (int x = 0; x < count; x++)
            {
                int rowX = x - sideCount;
                position[x * 6 + axe1] = rowX * divid;
                position[x * 6 + axe2] = -range;
                position[x * 6 + axe3] = 0;
                position[x * 6 + 3 + axe1] = rowX * divid;
                position[x * 6 + 3 + axe2] = +range;
                position[x * 6 + 3 + axe3] = 0;
            }
            for (int y = 0; y < count; y++)
            {
                int rowY = y - sideCount;
                position[count * 6 + y * 6 + axe1] = -range;
                position[count * 6 + y * 6 + axe2] = rowY * divid;
                position[count * 6 + y * 6 + axe3] = 0;
                position[count * 6 + y * 6 + 3 + axe1] = +range;
                position[count * 6 + y * 6 + 3 + axe2] = rowY * divid;
                position[count * 6 + y * 6 + 3 + axe3] = 0;
            }
            return new ArrayVertexData(new ShaderInfo.VertexRequestTagEnum[]{
                ShaderInfo.VertexRequestTagEnum.Position,
            }, new float[][]{
                position,
            }, OpenTK.Graphics.OpenGL4.PrimitiveType.Lines);
        }
        /// <summary>
        /// 获得一个三轴基准线的顶点数据
        /// </summary>
        /// <returns>顶点数据</returns>
        public static VertexData DatumLine()
        {
            return new ArrayVertexData(
                new ShaderInfo.VertexRequestTagEnum[]{
                    ShaderInfo.VertexRequestTagEnum.Position,
                    ShaderInfo.VertexRequestTagEnum.Color,
            }, new float[][]{
                //position
                new float[]
                {
                    -1000.0f,   0.0f,       0.0f,
                    1000.0f,    0.0f,       0.0f,
                    0.0f,       -1000.0f,   0.0f,
                    0.0f,       1000.0f,    0.0f,
                    0.0f,       0.0f,       -1000.0f,
                    0.0f,       0.0f,       1000.0f,
                },
                //color
                new float[]
                {
                    1.0f,   0.0f,   0.0f,
                    1.0f,   0.0f,   0.0f,
                    0.0f,   1.0f,   0.0f,
                    0.0f,   1.0f,   0.0f,
                    0.0f,   0.0f,   1.0f,
                    0.0f,   0.0f,   1.0f,
                }
            }, OpenTK.Graphics.OpenGL4.PrimitiveType.Lines);
        }

        public static VertexData Line(Vector3 pointStart, Vector3 pointEnd)
        {
            return Box();
        }

        public static VertexData Arrow(Vector3 pointStart, Vector3 pointEnd)
        {
            return Box();
        }

        public static VertexData Polygon(params Vector3[] point)
        {
            return Box();
        }

        public static VertexData Lines(params Vector3[] point)
        {
            return Box();
        }

        public static VertexData ConvexPolyhedron(params Vector3[] point)
        {
            return Box();
        }
    }
}
